#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include "mosquitto.h"
#include "cJSON.h"
#include "mqtt_sub.h"

// 定义运行标志决定是否需要结束
static int running = 1;

MqttSub::MqttSub()
{
        initMqtt();
}

MqttSub::MqttSub(std::string &host, int port) : host_(host), port_(port)
{
        initMqtt();
}

MqttSub::~MqttSub()
{
        // 结束后的清理工作
        mosquitto_destroy(mosq_);
        mosquitto_lib_cleanup();
        printf("End!\n");
}

void MqttSub::initMqtt()
{

        // 初始化mosquitto库
        mosquitto_lib_init();
        // 创建一个订阅端实例
        // 参数：id（不需要则为NULL）、clean_start、用户数据
        mosq_ = mosquitto_new("sub_mqtt", true, NULL);
        if (mosq_ == NULL)
        {
                std::cout << "创建mqtt服务端失败" << std::endl;
                return;
        }
        // 设置回调函数
        // std::function<void(struct mosquitto *mosq, void *obj, int rc)> func = [this](struct mosquitto *mosq, void *obj, int rc){;};
        // mosquitto_connect_callback_set(mosq_, func);
        mosquitto_connect_callback_set(mosq_, MqttSub::onConnectCallback);
        mosquitto_disconnect_callback_set(mosq_, MqttSub::onDisconnectCallback);
        mosquitto_subscribe_callback_set(mosq_, MqttSub::onSubscribeCallback);
        mosquitto_message_callback_set(mosq_, MqttSub::onMessageCallback);
        // 连接至服务器
        // 参数：句柄、ip（host）、端口、心跳
        if (mosquitto_connect(mosq_, host_.c_str(), port_, keep_alive_))
        {
                std::cout << "连接服务器失败" << std::endl;
                return;
        }
}

void MqttSub::run()
{
        while (running)
        {
                mosquitto_loop(mosq_, -1, 1);
        }
}

void MqttSub::onConnectCallback(struct mosquitto *mosq, void *obj, int rc)
{
        if (rc)
        {
                std::cout << "连接mqtt服务器时发生错误" << std::endl;
        }
        else
        {
                std::cout << "已连接到mqtt服务器" << std::endl;
                // 订阅话题
                //  订阅主题
                // 参数：句柄、id、订阅的主题、qos
                if (mosquitto_subscribe(mosq, NULL, "machine_info_analyze", 2))
                {
                        std::cout << "订阅话题失败" << std::endl;
                        exit(1);
                }
        }
}

void MqttSub::onDisconnectCallback(struct mosquitto *mosq, void *obj, int rc)
{
        std::cout << "连接被断开" << std::endl;
        running = 0;
}

void MqttSub::onSubscribeCallback(struct mosquitto *mosq, void *obj, int mid, int qos_count, const int *granted_qos)
{
        std::cout << "订阅已开启" << std::endl;
}

void MqttSub::onMessageCallback(struct mosquitto *mosq, void *obj, const struct mosquitto_message *msg)
{
        cJSON *root = cJSON_Parse((char *)msg->payload);
        if (root)
        {
                cJSON *car_top_p = cJSON_GetObjectItem(root, "car_top_p");
                if (car_top_p)
                {
                        int size = cJSON_GetArraySize(car_top_p);
                        for (int i = 0; i < size; i++)
                        {
                                cJSON *value = cJSON_GetArrayItem(car_top_p, i);
                                printf("%s ", cJSON_Print(value));
                        }
                        printf("\n******************\n");
                }
                cJSON *cabin_top_p = cJSON_GetObjectItem(root, "cabin_top_p");
                if (cabin_top_p)
                {
                        // printf("%s: ", cJSON_Print(cabin_top_p));
                        int size = cJSON_GetArraySize(cabin_top_p);
                        for (int i = 0; i < size; i++)
                        {
                                cJSON *p_i = cJSON_GetArrayItem(cabin_top_p, i);
                                int p_i_size = cJSON_GetArraySize(p_i);
                                for (int j = 0; j < p_i_size; j++)
                                {
                                        cJSON *value = cJSON_GetArrayItem(p_i, j);
                                        printf("%s ", cJSON_Print(value));
                                }
                                printf("\n");
                        }
                }
                cJSON *cabin_bottom_p = cJSON_GetObjectItem(root, "cabin_bottom_p");
                if(cabin_bottom_p)
                {

                }
                cJSON *cabin_slope_p = cJSON_GetObjectItem(root, "cabin_slope_p");
                if(cabin_slope_p)
                {

                }
                cJSON *cabin_slope = cJSON_GetObjectItem(root, "cabin_slope");
                if(cabin_slope)
                {

                }
                cJSON *timestamp = cJSON_GetObjectItem(root, "timestamp");
                if(timestamp)
                {
                        
                }
        }
        if (strcmp((char *)(msg->payload), "quit") == 0)
        {
                mosquitto_disconnect(mosq);
        }
}
